<template>
  <view class="tn-steps" :style="stepsStyle">
    <view
      v-for="(item, index) in data"
      :key="index"
      class="tn-steps__item"
      :class="[stepItemClass]"
      @tap.stop="handleItemClick(index + 1)"
    >
      <!-- 点模式 -->
      <view
        v-if="mode === 'dot'"
        class="tn-steps__mode tn-steps__mode--dot"
        :class="[stepModeClass(index + 1)]"
        :style="stepModeStyle(index + 1)"
      ></view>

      <!-- 数值模式 -->
      <view
        v-if="mode === 'number'"
        class="tn-steps__mode tn-steps__mode--number"
        :class="[stepModeClass(index + 1)]"
        :style="stepModeStyle(index + 1)"
      >
        <!-- 数值序号 -->
        <view class="number-index">
          {{ index + 1 }}
        </view>
        <!-- 数值图标 -->
        <view class="number-icon">
          <tn-icon :icon="modeIconValue(index)"></tn-icon>
        </view>
      </view>

      <!-- icon模式 -->
      <view
        v-if="mode === 'icon'"
        class="tn-steps__mode--icon"
        :class="[stepModeClass(index + 1)]"
        :style="stepModeStyle(index + 1)"
      >
        <tn-icon :icon="modeIconValue(index)"></tn-icon>
      </view>

      <!-- dotIcon模式 -->
      <view
        v-if="mode === 'dotIcon'"
        class="tn-steps__mode--dot-icon"
        :class="[stepModeClass(index + 1)]"
      >
        <view class="dot" :style="stepModeStyle(index + 1)"></view>
        <view class="icon" :style="stepModeStyle(index + 1)">
          <tn-icon :icon="modeIconValue(index)"></tn-icon>
        </view>
      </view>

      <!-- 文本内容 -->
      <view
        v-if="item?.title"
        class="tn-steps__title"
        :class="[stepModeClass(index + 1)]"
        :style="titleStyle(index + 1)"
      >{{ item.title }}</view>

      <!-- 连接横线 -->
      <view
        v-if="index < data.length - 1"
        class="tn-steps__line"
        :class="[stepModeClass(index + 2)]"
        :style="lineStyle(index + 2)"
      ></view>
    </view>
  </view>
</template>

<script lang="ts" setup>
import { stepsProps, stepsEmits, StepData } from '../../../types/tn-steps'
import { computed, CSSProperties, ref, watch } from 'vue'
import { UPDATE_MODEL_EVENT } from '../../../constants'
import TnIcon from '../../tn-icon/src/Icon.vue'

const props = defineProps(stepsProps)
const emits = defineEmits(stepsEmits)

// step数据
const data = computed<StepData[]>(() => {
  return props?.data || []
})
// 当前选中的index
let currentIndex = ref<number>(0)
watch(() => props.modelValue, (value: string | number) => {
  currentIndex.value = Number(value)
}, {
  immediate: true
})

// steps样式
const stepsStyle = computed<CSSProperties>(() => {
  let style: CSSProperties = {}
  // 步骤条方向
  if (props?.direction === 'horizontal') {
    style.flexDirection = 'row'
  } else if (props?.direction === 'vertical') {
    style.flexDirection = 'column'
  }
  return style
})
// stepMode样式
const stepModeStyle = computed<(index: number) => CSSProperties>(() => {
  return (index: number) => {
    let style: CSSProperties = {}
    const activeColor = data.value[index - 1]?.activeColor || props?.activeColor || ''
    const inactiveColor = data.value[index - 1]?.inactiveColor || props?.inactiveColor || ''
    if (props.mode === 'dot') {
      if (index <= currentIndex.value) {
        if (activeColor) style.backgroundColor = activeColor
      } else {
        if (inactiveColor) style.backgroundColor = inactiveColor
      }
    } else if (props.mode === 'number') {
      if (index <= currentIndex.value) {
        if (activeColor) {
          style.backgroundColor = activeColor
          style.borderColor = activeColor
          style.color = activeColor
        }
      } else {
        if (inactiveColor) {
          style.borderColor = inactiveColor
          style.color = inactiveColor
        }
      }
    } else if (props.mode === 'icon') {
      if (index <= currentIndex.value) {
        if (activeColor) style.color = activeColor
      } else {
        if (inactiveColor) style.color = inactiveColor
      }
    } else if (props.mode === 'dotIcon') {
      if (index <= currentIndex.value) {
        if (activeColor) style.color = activeColor
      } else {
        if (inactiveColor) style.backgroundColor = inactiveColor
      }
    } 
    return style
  }
})
// step标题样式
const titleStyle = computed<(index: number) => CSSProperties>(() => {
  return (index: number) => {
    let style: CSSProperties = {}
    const activeColor = data.value[index - 1]?.activeColor || props?.activeColor || ''
    const inactiveColor = data.value[index - 1]?.inactiveColor || props?.inactiveColor || ''
    if (index <= currentIndex.value) {
      if (activeColor) style.color = activeColor
    } else {
      if (inactiveColor) style.color = inactiveColor
    }
    return style
  }
})
// step横线样式
const lineStyle = computed<(index: number) => CSSProperties>(() => {
  return (index: number) => {
    let style: CSSProperties = {}
    const activeColor = data.value[index -1 ]?.activeColor || props?.activeColor || ''
    const inactiveColor = data.value[index - 1]?.inactiveColor || props?.inactiveColor || ''
    if (index <= currentIndex.value) {
      if (activeColor) style.borderColor = activeColor
    } else {
      if (inactiveColor) style.borderColor = inactiveColor
    }

    // 偏移位置
    let translateValue = 0
    if (props.mode === 'dot') {
      translateValue = uni.upx2px(20) / 2
    } else if(['icon', 'dotIcon'].includes(props.mode)) {
      translateValue = uni.upx2px(52) / 2
    } else {
      translateValue = uni.upx2px(44) / 2
    }
    // 根据不同的方向进行偏移
    if (props.direction === 'horizontal') {
      style.top = translateValue + 'px'
    } else if (props.direction === 'vertical') {
      style.left = translateValue + 'px'
    }
    return style
  }
})

// stepItem对应的类
const stepItemClass = computed<string>(() => {
  let clazz: string[] = []
  clazz.push(`tn-steps__item--${props?.direction || 'horizontal'}`)
  return clazz.join(' ')
})
// stepMode对应的类
const stepModeClass = computed<(index: number) => string>(() => {
  return (index: number) => {
    let clazz: string[] = []
    if (index <= currentIndex.value) {
      clazz.push('active')
    }
    return clazz.join(' ')
  }
})

// 获取对应的mode下的图标
const modeIconValue = computed<(index: number) => string>(() => {
  return (index: number) => {
    if (index <= currentIndex.value - 1) {
      return data.value[index].activeIcon || props.icon
    }
    return data.value[index].icon || props.icon
  }
})

// 处理item点击事件
const handleItemClick = (index: number) => {
  currentIndex.value = index
  emits(UPDATE_MODEL_EVENT, index)
  emits('change', index)
}
</script>

<script lang="ts">
export default {
  options: {
    // 在微信小程序中将组件节点渲染为虚拟节点，更加接近Vue组件的表现(不会出现shadow节点下再去创建元素)
    virtualHost: true
  }
}
</script>

<style lang="scss" scoped>
  @import '../../../theme.scss';

  $tn-steps-item-number-width: 44rpx;
  $tn-steps-item-dot-width: 20rpx;

  .tn-steps {
    display: flex;
    flex-direction: row;

    &__item {
      position: relative;
      flex: 1;
      display: flex;
      align-items: center;
      justify-content: center;
      flex-direction: column;
      min-width: 100rpx;
      text-align: center;

      &--horizontal {
        .tn-steps__title {
          margin-top: 14rpx;
        }
        .tn-steps__line {
          border-bottom-style: solid;
          width: 50%;
          left: 75%;
        }
      }
      &--vertical {
        flex-direction: row;
        justify-content: flex-start;
        min-height: 120rpx;
        .tn-steps__title {
          margin-left: 14rpx;
        }
        .tn-steps__line {
          border-left-style: solid;
          height: 50%;
          top: 75%;
        }
      }
    }

    &__title {
      transition: all 0.25s;
      color: #AAAAAA;
      &.active {
        color: $tn-main-color;
      }
    }

    &__line {
      border-color: #AAAAAA;
      position: absolute;
      transition: all 0.25s;
      border-width: 2rpx;
      &.active {
        border-color: $tn-main-color;
      }
    }

    &__mode {
      transition: all 0.25s;
      /* dot模式 start */
      &--dot {
        width: $tn-steps-item-dot-width;
        height: $tn-steps-item-dot-width;
        border-radius: 50%;
        background-color: #AAAAAA;

        &.active {
          background-color: $tn-main-color;
        }
      }
      /* dot模式 end */

      /* number模式 start */
      &--number {
        position: relative;
        width: $tn-steps-item-number-width;
        height: $tn-steps-item-number-width;
        line-height: calc(#{$tn-steps-item-number-width} - 2rpx);
        border: 1px solid #AAAAAA;
        border-radius: 50%;
        overflow: hidden;
        transition: all 0.25s linear;
        background-color: transparent;
        color: #AAAAAA;
        .number-index {
          position: absolute;
          top: 50%;
          left: 50%;
          transition: inherit;
          transform: translate(-50%, -50%);
          line-height: 1;
        }
        .number-icon {
          color: #FFFFFF;
          position: absolute;
          top: 50%;
          left: 50%;
          transition: inherit;
          transform: translate(-50%, 20%);
          line-height: 1;
        }
        &.active {
          background-color: $tn-main-color;
          border-color: $tn-main-color;
          .number-index {
            transform: translate(-50%, -150%);
          }
          .number-icon {
            transform: translate(-50%, -50%);
          }
        }
      }
      /* number模式 end */
      /* icon模式start */
      &--icon {
        width: calc($tn-steps-item-number-width + 8rpx);
        height: calc($tn-steps-item-number-width + 8rpx);
        font-size: $tn-steps-item-number-width;
        transition: all 0.25s linear;
        color: #AAAAAA;

        &.active {
          color: $tn-main-color;
        }
      }
      /* icon模式end */

      /* dotIcon模式 start */
      &--dot-icon {
        position: relative;
        width: calc($tn-steps-item-number-width + 8rpx);
        height: calc($tn-steps-item-number-width + 8rpx);
        font-size: $tn-steps-item-number-width;
        transition: all 0.25s linear;
        transform-origin: center center;
        display: flex;
        align-items: center;
        justify-content: center;
        .dot {
          position: absolute;
          width: $tn-steps-item-dot-width;
          height: $tn-steps-item-dot-width;
          border-radius: 50%;
          transition: inherit;
          transform-origin: inherit;
          transform: scale(1);
          background-color: #AAAAAA;
        }
        .icon {
          position: absolute;
          width: 100%;
          height: 100%;
          font-size: inherit;
          transition: inherit;
          transform-origin: inherit;
          transform: scale(0);
          color: #AAAAAA;
          background-color: transparent;
        }
        &.active {
          .dot {
            background-color: $tn-main-color;
            transform: scale(0);
          }
          .icon {
            color: $tn-main-color;
            transform: scale(1);
          }
        }
      }
      /* dotIcon模式 end */
    }
  }
</style>
